<!--
 * @Author: monet hanxu@huaun.com
 * @Date: 2023-09-21 16:04:41
 * @LastEditors: zhangyonggui
 * @LastEditTime: 2023-12-21 10:59:57
 * @FilePath: /h-radar-expose/pages/Exposure/ExposeList/IpDetial.vue
 * @Description:IP的详情页
-->
<template>
  <LayoutDetail
    :title-btn="titleBtn"
    :left-num="2"
    :head-num="3"
    :tabs-list="tabsList"
    :tab-active="tabActive"
    @showPrompt="showPrompt"
  >
    <!-- 左侧 -->
    <template #title>
      <el-tooltip effect="dark" :content="basicInfo.name" placement="bottom">
        <span>{{ basicInfo.name }}</span>
      </el-tooltip>
    </template>
    <template #content-title-1>基本信息</template>
    <template #content-body-1>
      <LayoutInfoList :info-list="infoList"></LayoutInfoList>
    </template>
    <template #content-title-2>标签</template>
    <template #content-body-2>
      <TagManip
        :dynamic-tags="basicInfo.tag"
        @handleClose="delTag"
        @handleAdd="addTag"
      ></TagManip>
    </template>
    <!--右侧 -->
    <template #right-head>
      <AssessmentBlock :block-list="blockList"></AssessmentBlock>
    </template>
    <template #tab-content-assetProfile>
      <LayoutDraw :left-num="2">
        <template #content-title-1>基础信息</template>
        <template #content-body-1>
          <LayoutFormList :form-list="baseInfo"></LayoutFormList>
        </template>
        <template #content-title-2>IP端口服务信息</template>
        <template #content-body-2>
          <el-form
            :inline="true"
            :model="tableConfig.params"
            class="table-search"
            @submit.native.prevent
          >
            <el-form-item label="端口号">
              <el-input
                v-model="tableConfig.params.port"
                placeholder="端口号"
                @keyup.enter.native="reloadTable"
              ></el-input>
            </el-form-item>
            <el-form-item label="服务">
              <el-input
                v-model="tableConfig.params.server"
                placeholder="服务"
                @keyup.enter.native="reloadTable"
              ></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="reloadTable">查询</el-button>
            </el-form-item>
          </el-form>
          <!-- <vul-table ref="table" v-bind="tableConfig"></vul-table> -->

          <el-table
            :data="tableConfig.tableData"
            class="info-table"
            max-height="605"
          >
            <el-table-column
              v-for="item in tableConfig.columns"
              :key="item.prop"
              :prop="item.prop"
              :label="item.label"
            >
              <template v-slot:default="scope">
                {{ scope.row[item.prop] || '--' }}
              </template>
            </el-table-column>
          </el-table>
          <el-pagination
            class="self-pagination"
            size="small"
            :current-page="tableConfig.params.pageNumber"
            :page-size="tableConfig.params.pageSize"
            :page-sizes="[5, 10, 15, 20, 50, 100]"
            :layout="'total, sizes, prev, pager, next, jumper'"
            :total="tableConfig.total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          >
          </el-pagination>
        </template>
        <template #right-title>资产变更记录</template>
        <template #right-body>
          <LayoutNoticeList :notice-list="noticeList"></LayoutNoticeList>
        </template>
      </LayoutDraw>
    </template>
    <template #tab-content-exposurePath>
      <GraphExposurePath :row-list="rowList"></GraphExposurePath>
    </template>
    <template #tab-content-associatedExposure>
      <GraphExposureSurface :row-list="rowList"></GraphExposureSurface>
    </template>
    <template #tab-content-surfaceAnalysis>
      <LayoutDraw :left-num="2" :left-span="24" :right-span="0">
        <template #content-title-1>资产攻击面图谱</template>
        <template #content-body-1>
          <GraphSurfaceAnalysis :row-list="rowList"></GraphSurfaceAnalysis>
        </template>
        <template #content-title-2>资产弱点</template>
        <template #content-body-2>
          <!-- <vul-table ref="table" v-bind="tableConfig2"></vul-table> -->
          <el-table :data="tableConfig2.tableData" class="info-table">
            <el-table-column
              v-for="item in tableConfig2.columns"
              :key="item.prop"
              :prop="item.prop"
              :label="item.label"
            >
              <template v-slot:default="scope">
                {{ scope.row.label || '--' }}
              </template>
            </el-table-column>
          </el-table>
          <el-pagination
            class="self-pagination"
            size="small"
            :current-page="tableConfig2.params.pageNumber"
            :page-size="tableConfig2.params.pageSize"
            :page-sizes="[5, 10, 15, 20, 50, 100]"
            :layout="'total, sizes, prev, pager, next, jumper'"
            :total="tableConfig2.total"
            @size-change="handleSizeChange2"
            @current-change="handleCurrentChange2"
          >
          </el-pagination>
        </template>
      </LayoutDraw>
    </template>
  </LayoutDetail>
</template>

<script lang="ts" setup>
import LayoutDetail from '@/components/Expose/Layout/Detail.vue';
import LayoutInfoList from '@/components/Expose/Layout/InfoList.vue';
import LayoutFormList from '@/components/Expose/Layout/FormList.vue';
import LayoutExpandableBox from '@/components/Expose/Layout/ExpandableBox.vue';
import LayoutNoticeList from '@/components/Expose/Layout/NoticeList.vue';
import LayoutDraw from '@/components/Expose/Layout/Draw.vue';
import GraphExposurePath from '@/components/Expose/Graph/ExposurePath.vue';
import GraphExposureSurface from '@/components/Expose/Graph/ExposureSurface.vue';
import GraphSurfaceAnalysis from '@/components/Expose/Graph/SurfaceAnalysis.vue';
import ModelList from '@/components/Expose/ModelList.vue';
import TagManip from '@/components/Expose/TagManip.vue';
import AssessmentBlock from '@/components/Expose/AssessmentBlock.vue';
import ShowCode from '@/components/Expose/ShowCode.vue';
import noData from '@/components/Expose/noData.vue';
import { usewebDetail } from '@/composables/Expose/usewebDetail';
import { useRoute } from 'vue-router';
import { ref, reactive, computed, onMounted } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const route = useRoute();
const {
  detialInfo,
  basicInfo,
  delTag,
  addTag,
  showPrompt,
  category,
  changeList,
  blockList,
  getDetialById,
  getLeftBaseInfo,
  getAssetChanged,
  getAnalysis,
} = usewebDetail();
const id = ref(route.query.id || '');
const tabActive = ref('assetProfile');
const tabsList = ref([
  {
    name: 'assetProfile',
    label: '资产画像',
    disabled: false,
  },
  {
    name: 'exposurePath',
    label: '资产暴露路径',
    disabled: false,
  },
  {
    name: 'associatedExposure',
    label: '关联暴露面',
    disabled: false,
  },
  {
    name: 'surfaceAnalysis',
    label: '攻击面分析',
    disabled: false,
  },
]);

const tableConfig = reactive<any>({
  uri: 'detail/getPortById',
  params: {
    port: '',
    server: '',
    ipId: id,
    pageNumber: 1,
    pageSize: 10,
  },
  tableAttr: {
    'max-height': '605px',
  },
  columns: [
    {
      label: '开放端口',
      prop: 'port',
    },
    {
      label: '协议',
      prop: 'protocol',
    },
    {
      label: '服务',
      prop: 'server',
    },
    {
      label: '上次存活时间',
      prop: 'lastAliveTime',
    },
  ],
  tableData: [],
  total: 0,
});
const tableConfig2 = reactive({
  uri: 'detail/getWeaknessList',
  params: {
    asmType: '',
    vulLevel: '',
    vulId: '',
    assetType: 'ip',
    assetId: id,
    pageNumber: 1,
    pageSize: 10,
  },
  tableAttr: {
    'max-height': '605px',
  },
  columns: [
    {
      label: '弱点名称',
      prop: 'vulName',
    },
    {
      label: '漏洞编号',
      prop: 'vulCode',
    },
    {
      label: '风险等级',
      prop: 'vulLevel',
      render: (h, c) => {
        let obj = {
          0: '信息',
          1: '低危',
          2: '中危',
          3: '高危',
          4: '超危',
        };
        let val = obj[Number(c.row.vulLevel)];
        return h('div', { style: {} }, val);
      },
    },
    {
      label: '弱点类型',
      prop: 'asmType',
    },
    {
      label: '发现时间',
      prop: 'insertTime',
    },
    {
      label: '弱点存在位置',
      prop: 'bugUrl',
    },
  ],
  tableData: [],
  total: 0,
});
const titleBtn = computed(() => {
  const urlList = ['http', 'https'];
  let array = [
    {
      flag: 'url',
      tip: '访问',
      icon: 'vul-icon-url',
    },
  ];

  if (!urlList.includes(detialInfo.value.protocol)) {
    array = array.filter((el) => el.flag !== 'url');
  }

  return array;
});
const infoList = computed(() => {
  const { dataStatus, isAlive, createTime, updateTime, company } =
    basicInfo.value;

  const foundStatus = store.state.enum.assetStatus.find(
    (status) => status.type === parseInt(dataStatus),
  );

  return [
    {
      label: '更新状态',
      icon: 'vul-icon-type',
      type: 'tag',
      tag: foundStatus ? foundStatus.tag : '',
      content: foundStatus ? foundStatus.value : '未知',
    },
    {
      label: '存活状态',
      icon: 'vul-icon-type',
      type: 'img',
      src: isAlive
        ? require(`@/static/images/icon/survival-${parseInt(isAlive)}.png`)
        : '',
    },
    {
      label: '首次发现',
      icon: 'vul-icon-time',
      content: createTime,
    },
    {
      label: '数据更新',
      icon: 'vul-icon-time',
      content: updateTime,
    },
    {
      label: '所属单位',
      icon: 'vul-icon-company',
      content: company,
    },
  ];
});
const baseInfo = computed(() => {
  const {
    ip,
    type,
    os,
    operators,
    scene,
    province,
    countryName,
    city,
    asNumber,
    asOrg,
  } = detialInfo.value;

  const typeList = {
    1: 'IPV4',
    2: 'IPV6',
  };

  const addr = `${countryName}·${province}·${city}`;
  return [
    {
      label: 'IP地址',
      content: ip,
    },

    {
      label: 'IP类型',
      content: typeList[type],
    },
    {
      label: '操作系统',
      content: os,
    },
    {
      label: '服务商',
      content: operators,
    },

    {
      label: '应用场景',
      content: scene,
    },
    {
      label: '地理位置',
      content: addr === '··' ? '' : addr,
    },
    {
      label: 'ASN',
      content: asNumber,
    },
    {
      label: 'ASN组织',
      content: asOrg,
    },
  ];
});
const noticeList = computed(() => {
  return changeList.value.map(
    ({ fieldAlias, newValue, oldValue, changeTime, opType }) => {
      const btn = store.state.enum.changeStatus.find(
        ({ type }) => type === opType,
      );

      return {
        title: fieldAlias,
        content: opType === 3 ? oldValue : newValue,
        time: changeTime,
        type: btn ? btn.tag : '',
        typeText: btn ? btn.value : '',
      };
    },
  );
});
const rowList = computed(() => {
  return {
    assetId: id.value,
    assetType: category.value,
  };
});
onMounted(async () => {
  category.value = 'ip';
  await getDetialById('detail/getIpById');
  await getLeftBaseInfo();
  await getAnalysis();
  await getAssetChanged();
  await getPortDetais();
  await getSurfaceDetais();
});
const getPortDetais = async () => {
  let { params } = tableConfig;
  const { code, data } = await store.dispatch('detail/getPortById', params);
  if (code == 0) {
    let { list, total } = data;
    tableConfig.tableData = list || [];
    tableConfig.total = total;
  }
};
const handleSizeChange = async (v) => {
  tableConfig.params.pageSize = v;
  await getPortDetais();
};
const handleCurrentChange = async (v) => {
  tableConfig.params.pageNumber = v;
  await getPortDetais();
};
const reloadTable = () => {
  // this.$refs.table.reload()
  tableConfig.params.pageNumber = 1;
  getPortDetais();
};
const getSurfaceDetais = async () => {
  let { params } = tableConfig2;
  const { code, data } = await store.dispatch('detail/getWeaknessList', params);
  if (code == 0) {
    let { list, total } = data;
    tableConfig2.tableData = list || [];
    tableConfig2.total = total;
  }
};
const handleSizeChange2 = async (v) => {
  tableConfig2.params.pageSize = v;
  await getSurfaceDetais();
};
const handleCurrentChange2 = async (v) => {
  tableConfig2.params.pageNumber = v;
  await getSurfaceDetais();
};
</script>
<style lang="scss" scoped>
.table-search {
  margin-top: $-v-spacing-horizontal-base;
  text-align: right;
}

.self-pagination {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;

  ::v-deep .el-pagination__total {
    margin-right: 19px;
    color: rgb(60, 84, 113);
    font-size: 12px !important;
  }

  ::v-deep .el-select .el-input {
    width: 100px;
    margin: 0px 5px;
  }

  ::v-deep .el-select {
    width: 110px;
  }

  ::v-deep .el-input .el-input__inner {
    font-size: 13px;
  }

  ::v-deep .el-pagination__jump {
    margin-left: 5px;
    color: rgb(60, 84, 113);
    font-size: 12px !important;
  }

  ::v-deep .el-pagination__editor.el-input {
    width: 50px;
  }

  ::v-deep .el-select__wrapper {
    font-size: 12px !important;
  }

  ::v-deep .el-pagination__sizes {
    margin-left: 0;
  }

  ::v-deep .el-pager li {
    font-size: 12px !important;
  }
}

.info-table {
  ::v-deep thead th {
    font-weight: 500;
  }
}
</style>
